package com.mzba.place.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;

import junit.framework.Assert;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.Log;

import com.baidu.mapapi.map.MapView;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.baidu.platform.comapi.map.Projection;
import com.mzba.place.BasicActivity;
import com.mzba.place.R;

/**
 * 
 * @author 06peng
 *
 */
public class Utils {
	
	private static final String TAG = "++++++++++++Place.Util++++++++++++";

	public static Bitmap getBitmap(Context context, String url) {
		ImageMemoryCache  memoryCache = new ImageMemoryCache(context);
	    // 从内存缓存中获取图片
	    Bitmap result = null;
	    try {
	    	result = memoryCache.getBitmapFromCache(url);
	    	if (result == null) {
		        // 文件缓存中获取
		    	ImageFileCache fileCache = new ImageFileCache();
		        result = fileCache.getImage(url);
		        if (result == null) {
		            // 从网络获取
		            result = ImageGetFromHttp.downloadBitmap(url);
		            if (result != null) {
		                fileCache.saveBitmap(result, url);
		                memoryCache.addBitmapToCache(url, result);
		            }
		        } else {
		            // 添加到内存缓存
		            memoryCache.addBitmapToCache(url, result);
		        }
		    }
		} catch (Exception e) {
			e.printStackTrace();
		}
	    return result;
	}
	
	/** 从缓存中获取图片 **/
    public static File getImageFile(Context context, String url) { 
    	File file = null;
    	ImageFileCache fileCache = new ImageFileCache();
    	Bitmap bitmap = getBitmap(context, url);
    	String[] strs = url.split("/");
    	String filename = strs[strs.length - 1];
        String dir = fileCache.getDirectory();
        File dirFile = new File(dir);
        if (!dirFile.exists())
            dirFile.mkdirs();
        file = new File(dir +"/" + filename);
        try {
            file.createNewFile();
            OutputStream outStream = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
            outStream.flush();
            outStream.close();
            bitmap.recycle();
            bitmap = null;
        } catch (FileNotFoundException e) {
            Log.w("ImageFileCache", "FileNotFoundException");
        } catch (IOException e) {
            Log.w("ImageFileCache", "IOException");
        }
        return file;
    }
    
    public static File getImageFileByBitmap(Bitmap bitmap, String url) {
    	File file = null;
    	ImageFileCache fileCache = new ImageFileCache();
    	String filename = fileCache.convertUrlToFileName(url);
        String dir = fileCache.getDirectory();
        File dirFile = new File(dir);
        if (!dirFile.exists())
            dirFile.mkdirs();
        file = new File(dir +"/" + filename);
        try {
            file.createNewFile();
            OutputStream outStream = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
            outStream.flush();
            outStream.close();
        } catch (FileNotFoundException e) {
            Log.w("ImageFileCache", "FileNotFoundException");
        } catch (IOException e) {
            Log.w("ImageFileCache", "IOException");
        }
        return file;
    }
	
	/**
	 * 获取屏幕左上角的坐标
	 * @param mMapView
	 * @return
	 */
	public static GeoPoint getLeftTopPoint(MapView mMapView) {
//		GeoPoint centerPoint = mMapView.getMapCenter();// 地图中心坐标
//        int tbSpan = mMapView.getLatitudeSpan();// 当前纬线的跨度（从地图的上边缘到下边缘）
//        int lrSpan = mMapView.getLongitudeSpan();// 当前经度的跨度(从地图的左边缘到地图的右边缘)
//        GeoPoint ltPoint = new GeoPoint(centerPoint.getLatitudeE6() + tbSpan / 2, centerPoint.getLongitudeE6() - lrSpan / 2);// 左上角坐标
		Projection p = mMapView.getProjection();
		GeoPoint ltPoint = p.fromPixels(0, ((BasicActivity) AppContext.getContext()).CanvasHeight);
        Log.i(TAG, "Left GeoPoint:" + ltPoint.getLongitudeE6() / 1E6 + "," + ltPoint.getLatitudeE6() / 1E6);
		return ltPoint;
	}
	
	/**
	 * 获取屏幕右下角的坐标
	 * @param mMapView
	 * @return
	 */
	public static GeoPoint getRightBottmPoint(MapView mMapView) {
//		GeoPoint centerPoint = mMapView.getMapCenter();// 地图中心坐标
//        int tbSpan = mMapView.getLatitudeSpan();// 当前纬线的跨度（从地图的上边缘到下边缘）
//        int lrSpan = mMapView.getLongitudeSpan();// 当前经度的跨度(从地图的左边缘到地图的右边缘)
//        GeoPoint rbPoint = new GeoPoint(centerPoint.getLatitudeE6() - tbSpan / 2, centerPoint.getLongitudeE6() + lrSpan / 2);// 右下角坐标
		Projection p = mMapView.getProjection();
		GeoPoint rbPoint = p.fromPixels(((BasicActivity) AppContext.getContext()).CanvasWidth, 0);
        Log.i(TAG, "Right GeoPoint:" + rbPoint.getLongitudeE6() / 1E6 + "," + rbPoint.getLatitudeE6() / 1E6);
        return rbPoint;
	}
	
	
	public static String[] getReportType(Context context){
		Resources res = context.getResources();
		String[] reportType = res.getStringArray(R.array.reportType);
		return reportType;
	}
	
	public static String[] getReportTime(Context context) {
		Resources res = context.getResources();
		return res.getStringArray(R.array.reportTime);
	}
	
	public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		bmp.compress(CompressFormat.PNG, 100, output);
		if (needRecycle) {
			bmp.recycle();
		}
		
		byte[] result = output.toByteArray();
		try {
			output.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return result;
	}
	
	public static byte[] getHtmlByteArray(final String url) {
		 URL htmlUrl = null;     
		 InputStream inStream = null;     
		 try {         
			 htmlUrl = new URL(url);         
			 URLConnection connection = htmlUrl.openConnection();         
			 HttpURLConnection httpConnection = (HttpURLConnection)connection;         
			 int responseCode = httpConnection.getResponseCode();         
			 if(responseCode == HttpURLConnection.HTTP_OK){             
				 inStream = httpConnection.getInputStream();         
			  }     
			 } catch (MalformedURLException e) {               
				 e.printStackTrace();     
			 } catch (IOException e) {              
				e.printStackTrace();    
		  } 
		byte[] data = inputStreamToByte(inStream);

		return data;
	}
	
	public static byte[] inputStreamToByte(InputStream is) {
		try{
			ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
			int ch;
			while ((ch = is.read()) != -1) {
				bytestream.write(ch);
			}
			byte imgdata[] = bytestream.toByteArray();
			bytestream.close();
			return imgdata;
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static byte[] readFromFile(String fileName, int offset, int len) {
		if (fileName == null) {
			return null;
		}

		File file = new File(fileName);
		if (!file.exists()) {
			Log.i(TAG, "readFromFile: file not found");
			return null;
		}

		if (len == -1) {
			len = (int) file.length();
		}

		Log.d(TAG, "readFromFile : offset = " + offset + " len = " + len + " offset + len = " + (offset + len));

		if(offset <0){
			Log.e(TAG, "readFromFile invalid offset:" + offset);
			return null;
		}
		if(len <=0 ){
			Log.e(TAG, "readFromFile invalid len:" + len);
			return null;
		}
		if(offset + len > (int) file.length()){
			Log.e(TAG, "readFromFile invalid file len:" + file.length());
			return null;
		}

		byte[] b = null;
		try {
			RandomAccessFile in = new RandomAccessFile(fileName, "r");
			b = new byte[len]; // 创建合适文件大小的数组
			in.seek(offset);
			in.readFully(b);
			in.close();

		} catch (Exception e) {
			Log.e(TAG, "readFromFile : errMsg = " + e.getMessage());
			e.printStackTrace();
		}
		return b;
	}
	
	private static final int MAX_DECODE_PICTURE_SIZE = 1920 * 1440;
	public static Bitmap extractThumbNail(final String path, final int height, final int width, final boolean crop) {
		Assert.assertTrue(path != null && !path.equals("") && height > 0 && width > 0);

		BitmapFactory.Options options = new BitmapFactory.Options();

		try {
			options.inJustDecodeBounds = true;
			Bitmap tmp = BitmapFactory.decodeFile(path, options);
			if (tmp != null) {
				tmp.recycle();
				tmp = null;
			}

			Log.d(TAG, "extractThumbNail: round=" + width + "x" + height + ", crop=" + crop);
			final double beY = options.outHeight * 1.0 / height;
			final double beX = options.outWidth * 1.0 / width;
			Log.d(TAG, "extractThumbNail: extract beX = " + beX + ", beY = " + beY);
			options.inSampleSize = (int) (crop ? (beY > beX ? beX : beY) : (beY < beX ? beX : beY));
			if (options.inSampleSize <= 1) {
				options.inSampleSize = 1;
			}

			// NOTE: out of memory error
			while (options.outHeight * options.outWidth / options.inSampleSize > MAX_DECODE_PICTURE_SIZE) {
				options.inSampleSize++;
			}

			int newHeight = height;
			int newWidth = width;
			if (crop) {
				if (beY > beX) {
					newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);
				} else {
					newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);
				}
			} else {
				if (beY < beX) {
					newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);
				} else {
					newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);
				}
			}

			options.inJustDecodeBounds = false;

			Log.i(TAG, "bitmap required size=" + newWidth + "x" + newHeight + ", orig=" + options.outWidth + "x" + options.outHeight + ", sample=" + options.inSampleSize);
			Bitmap bm = BitmapFactory.decodeFile(path, options);
			if (bm == null) {
				Log.e(TAG, "bitmap decode failed");
				return null;
			}

			Log.i(TAG, "bitmap decoded size=" + bm.getWidth() + "x" + bm.getHeight());
			final Bitmap scale = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true);
			if (scale != null) {
				bm.recycle();
				bm = scale;
			}

			if (crop) {
				final Bitmap cropped = Bitmap.createBitmap(bm, (bm.getWidth() - width) >> 1, (bm.getHeight() - height) >> 1, width, height);
				if (cropped == null) {
					return bm;
				}

				bm.recycle();
				bm = cropped;
				Log.i(TAG, "bitmap croped size=" + bm.getWidth() + "x" + bm.getHeight());
			}
			return bm;

		} catch (final OutOfMemoryError e) {
			Log.e(TAG, "decode bitmap failed: " + e.getMessage());
			options = null;
		}

		return null;
	}
	
	public static int[] getReportTypeIcon(){
		int[] reportTypeIcon = new int[]{R.drawable.ic_map_marker_01, R.drawable.ic_map_marker_02, R.drawable.ic_map_marker_03, R.drawable.ic_map_marker_04};
		return reportTypeIcon;
	}
	
	public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	
	public static String getCreateAt(String srcDate) {
		if (srcDate == null) {
			return "未知";
		}
		String destDate = "";
		try {
			srcDate = fromCalendar(toCalendar(srcDate));
			Date date = null;
			date = sdf.parse(srcDate);
			
			long now = System.currentTimeMillis();
			Long seconds = (now - date.getTime()) / 1000;
			
			long months = seconds / (30 * 24 * 60 * 60);
			long days = seconds / (24 * 60 * 60);
			long hours = seconds / (60 * 60);
			long minutes = seconds / 60;
			if (months > 0) {
				destDate = sdf.format(date);
			} else if (days > 0) {
				destDate = days + "天前";
			} else if (hours > 0) {
				destDate = hours + "小时前";
			} else if (minutes > 0) {
				destDate = minutes + "分钟前";
			} else {
				destDate = "刚刚";
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return destDate;
	}
	
	public static String fromCalendar(final Calendar calendar) {
        Date date = calendar.getTime();
        String formatted = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(date);
        String result = formatted.substring(0, 10) + " " + formatted.substring(11, 16);
        return result;
    }


    /** Transform ISO 8601 string to Calendar. */
    public static Calendar toCalendar(final String iso8601string) throws ParseException {
        Calendar calendar = GregorianCalendar.getInstance();
        String s = iso8601string.replace("Z", "+00:00");
        try {
            s = s.substring(0, 22) + s.substring(23);
        } catch (IndexOutOfBoundsException e) {
            throw new ParseException("Invalid length", 0);
        }
        Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
        calendar.setTime(date);
        return calendar;
    }
    
    public static String getCurrentTime() {
    	Date now = new Date();
    	return sdf.format(now);
    }
    
    /**
	 * 将Drawable转化为Bitmap
	 * @param drawable
	 * @return
	 */
	public static Bitmap drawableToBitmap(Drawable drawable) {
		Bitmap bitmap = Bitmap
				.createBitmap(
						drawable.getIntrinsicWidth(),
						drawable.getIntrinsicHeight(),
						drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
								: Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
				drawable.getIntrinsicHeight());
		drawable.draw(canvas);
		return bitmap;
	}
	
	/**
	 * 下载图片到SD卡
	 * @param imagePath
	 */
	public static void downLoadImage(String imageUrl, String path, String fileName) {
		if (fileName == null) {
			fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
		}
		File dir = new File(Environment.getExternalStorageDirectory() + "/" + path);
		if(!dir.exists()) {
			dir.mkdirs();
		}
		File file = new File(dir + File.separator + fileName);
		if (!file.exists()) {
			URL url;
			try {
				url = new URL(imageUrl);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.setRequestMethod("GET");
				conn.setReadTimeout(5 * 1000);
				if (conn.getResponseCode() == 200) {
					InputStream is = conn.getInputStream();
					byte[] data = readStream(is);

					FileOutputStream fs = new FileOutputStream(file);
					fs.write(data);
					fs.close();
				} else {
					System.out.println("请求失败");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 读取输入流数据
	 * @param is
	 * @return
	 * @throws Exception
	 */
	public static byte[] readStream(InputStream is) throws Exception {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		byte[] buffer = new byte[2048];
		int len = 0;
		while ((len = is.read(buffer)) != -1) {
			os.write(buffer, 0, len);
		}
		is.close();
		return os.toByteArray();
	}
	
	/**
	 * 转换图片成圆形图片
	 * @param bitmap
	 * @return
	 */
	public static Bitmap toRoundBitmap(Bitmap bitmap) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		float roundPx;
		float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
		if (width <= height) {
			roundPx = width / 2;
			top = 0;
			bottom = width;
			left = 0;
			right = width;
			height = width;
			dst_left = 0;
			dst_top = 0;
			dst_right = width;
			dst_bottom = width;
		} else {
			roundPx = height / 2;
			float clip = (width - height) / 2;
			left = clip;
			right = width - clip;
			top = 0;
			bottom = height;
			width = height;
			dst_left = 0;
			dst_top = 0;
			dst_right = height;
			dst_bottom = height;
		}

		Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect src = new Rect((int) left, (int) top, (int) right,
				(int) bottom);
		final Rect dst = new Rect((int) dst_left, (int) dst_top,
				(int) dst_right, (int) dst_bottom);
		final RectF rectF = new RectF(dst);

		paint.setAntiAlias(true);

		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, src, dst, paint);
		return output;
	}
	
	
	public static HashMap<String, String> getNotificationType(Context context){
		HashMap<String, String> notificationType = new HashMap<String, String>();
		notificationType.put("vote", context.getString(R.string.notification_vote));
		notificationType.put("caution", context.getString(R.string.notification_caution));
		notificationType.put("mine_comment", context.getString(R.string.notification_mine_comment));
		notificationType.put("star_comment", context.getString(R.string.notification_star_comment));
		
		return notificationType;
	}
}
